#region Summary

// 
// Owner : JackieHan 
// 
// Solution : Jackie.Utility
// 
// Project :Jackie.Utility
// 
// File : JackieValidator.cs
// 
// CopyRight : Copyright © 2009-2010 JackieHan Personal, All Rights Reserved 
// 
// Summary : 自定义的验证
// 
// History : 
//			2010-08-31 16:11:08	    Create 
// 

#endregion

#region Using

using System;
using System.Collections;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Jackie.Utility.CustomException;
using Jackie.Utility.CustomExtension;

#endregion

namespace Jackie.Utility
{
    /// <summary> 
    /// 自定义的验证
    /// </summary> 
    public class JackieValidator
    {
        private static readonly Type CollectionType = typeof(IEnumerable); //所有集合必须实现此接口使之可以迭代，所有集合都应该支持迭代

        /// <summary>
        /// 判断一个类型是否是集合,注意string类型也是集合
        /// </summary>
        /// <remarks>
        ///   判定标准为所有标准集合都应该实现IEnumerable接口来支持迭代
        /// </remarks>
        /// <param name="typeT">需要判断的类型</param>
        /// <returns>真：true,假：false</returns>
        public static bool IsCollection(Type typeT)
        {
            return CollectionType.IsAssignableFrom(typeT);
        }

        /// <summary>
        /// 判断文件类型是否为给定类型
        /// </summary>
        /// <param name="file">文件地址或文件名</param>
        /// <param name="fileTypes">给定文件类型</param>
        /// <returns></returns>
        public static bool IsFileExtension(string file, FileType fileTypes)
        {
            var extensionIndex = file.LastIndexOf(".");
            if (extensionIndex == -1)
            {
                var exception = new Exception("prameter's format is error!");
                throw exception;
            }
            var extension = file.Substring(extensionIndex, file.Length - 1);
            var fileType = JackieConvertor.ToFileType(extension);
            return (fileType & fileTypes) == fileType;
        }



        /// <summary>
        /// 是否为正整数
        /// </summary>
        /// <param name="inputText">输入字符串</param>
        /// <returns></returns>
        public static bool IsSinglessInteger(string inputText)
        {
            var regex = new Regex(SinglessIntegerRegexExpression);
            return regex.IsMatch(inputText);
        }

        /// <summary>
        /// 是否是版本号
        /// </summary>
        /// <param name="version"></param>
        /// <returns></returns>
        public static bool IsVersion(string version)
        {
            var versionBlocks = version.Split(new[] { '.' });
            if (versionBlocks.Length != 4)
            {
                throw new FormatException("版本号必须由四部分组成，用.号隔开。分别为主版本号，次版本号，内部版本号，修订号");
            }
            var major = versionBlocks[0];
            if (!IsSinglessInteger(major) || (major.Length > 4))
            {
                throw new FormatException("主版本号必须由数字组成");
            }
            var minor = versionBlocks[1];
            if (!IsSinglessInteger(minor) || (major.Length > 4))
            {
                throw new FormatException("次版本号必须有数字组成");
            }
            var build = versionBlocks[2];
            if (!IsSinglessInteger(build) || (major.Length > 4))
            {
                throw new FormatException("内部版本号必须有数字组成");
            }
            var revision = versionBlocks[3];
            if (!IsSinglessInteger(revision) || (revision.Length != 8))
            {
                throw new FormatException("修订号必须由8位数字组成，年年月月日日+当日发布次数");
            }
            return true;
        }

        /// <summary>
        /// 获取字符串MD5hash结果
        /// </summary>
        /// <param name="sourceStr">源字串</param>
        /// <param name="encoding">编码</param>
        /// <param name="isUppercase">结果是大写？</param>
        /// <returns></returns>
        public static string GetMd5String(string sourceStr, Encoding encoding, bool isUppercase)
        {
            var md5 = MD5.Create();
            var bytes = md5.ComputeHash(encoding.GetBytes(sourceStr));

            var resultBuilder = new StringBuilder();
            foreach (var hex in bytes.Select(b => b.ToString(isUppercase ? "X2" : "x2")))
            {
                resultBuilder.Append(hex);
            }
            return resultBuilder.ToString();
        }


        /// <summary>
        /// 判断是否为字母
        /// </summary>
        /// <param name="character">单个字符</param>
        /// <returns></returns>
        public static bool IsLetter(char character)
        {
            var regex = new Regex(LetterRegexExpression);
            return regex.IsMatch(character.ToString());
        }


        /// <summary>
        /// 是否为数字
        /// </summary>
        /// <param name="character">单个字符</param>
        /// <returns></returns>
        public static bool IsDigit(char character)
        {
            var regex = new Regex(DigitRegexExpression);
            return regex.IsMatch(character.ToString());
        }


        /// <summary>
        /// 是否为数字或者字母
        /// </summary>
        /// <param name="character">单个字符</param>
        /// <returns></returns>
        public static bool IsLetterOrDigit(char character)
        {
            var regex = new Regex(LetterOrDigitRegexExpression);
            return regex.IsMatch(character.ToString());
        }


        /// <summary>
        /// 是否为空白字符
        /// </summary>
        /// <param name="character">单个字符</param>
        /// <returns></returns>
        public static bool IsSpace(char character)
        {
            var regex = new Regex(SpaceRegexExpression);
            return regex.IsMatch(character.ToString());
        }



        /// <summary>
        /// 是否关系运算符号，包好等号
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        public static bool IsRelationalOperator(char character)
        {
            var regex = new Regex(RelopRegexExpression);
            return regex.IsMatch(character.ToString());
        }

        /// <summary>
        /// 正整数
        /// </summary>
        public const string SinglessIntegerRegexExpression = @"^\d+$";
        /// <summary>
        /// 单个关系运算符号
        /// </summary>
        public const string RelopRegexExpression = "^[\\>|\\<|=|!|\\||&]$";
        /// <summary>
        /// 单个空白
        /// </summary>
        public const string SpaceRegexExpression = "^\\s$";
        /// <summary>
        /// 单个数字或字母
        /// </summary>
        public const string LetterOrDigitRegexExpression = "^[a-zA-Z0-9]$";
        /// <summary>
        /// 单个数字
        /// </summary>
        public const string DigitRegexExpression = "^[0-9]$";
        /// <summary>
        /// 单个字母
        /// </summary>
        public const string LetterRegexExpression = "^[a-zA-Z]$";

        /// <summary>
        /// 浮点数
        /// </summary>
        public const string FloatRegexExpression = @"^[0-9]\d*(\.\d*|0\.\d*[1-9]\d*)?$";
    }
}